package com.cotte.flow.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.cotte.flow.model.DgraphRelations;
import com.cotte.flow.model.DgraphSteps;
import com.cotte.flow.model.Relation;
import com.cotte.flow.model.Step;
import com.cotte.flow.repository.OracleRepository;
import com.cotte.flow.repository.SqlServerRepository;
import com.cotte.flow.util.Client;
import com.google.gson.Gson;
import com.google.protobuf.ByteString;

import io.dgraph.DgraphClient;
import io.dgraph.DgraphProto.Mutation;
import io.dgraph.Transaction;

@Service
public class OrderStepDgraphService {
	
	private static final Logger logger = LoggerFactory.getLogger(StepDgraphService.class);
	private static DgraphClient dgraphClient = Client.createDgraphClient(false);
	private static Gson gson = new Gson();
	
	@Value("${dgraph.steps.name.prefix}")
	private String STEP_NAME;
	@Value("${dgraph.relations.name.prefix}")
	private String RELATION_NAME;
	
	@Value("${dgraph.order.steps.name.prefix}")
	private String ORDER_STEP_NAME;
	
	@Value("${dgraph.order.relations.name.prefix}")
	private String ORDER_RELATION_NAME;
	
	@Autowired
	private SqlServerRepository mes;
	
	@Autowired
	private OracleRepository bl;
	
	@Autowired
	private StepDgraphService stepService;
	
	public void orderCreate(String version,String syscode,String depart,String cate,String createTime) throws Exception {
		Transaction txn = dgraphClient.newTransaction();
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
		/**
		 * 根据车间、品类和时间匹配版本
		 * 1、先查询所有版本的总图
		 * 2、进行匹配选出符合的版本
		 */
		String name = null;
		List<String> allVersion = stepService.getAllVersion(version);
		String finalTime = null;
		String fzfl = null;
		if("MXF".equals(cate)) {
			fzfl = "XF";
		}
		//筛选出同一车间同一品类的版本
		List<String> needVersion = new ArrayList<>();
		for(String str:allVersion) {
			String[] arr = str.split("_");
			if(arr.length == 5) {
				String cj = arr[2];
				String pl = arr[3];
				if(depart.equals(cj) && fzfl.equals(pl)) {
					needVersion.add(str);
				}
			}
		}
		for(int i=0;i<needVersion.size();i++) {
			String nextTime = null;
			String[] arr = needVersion.get(i).split("_");
			String time = arr[4];
			if(i<needVersion.size()-1) {
				String[] next_arr = needVersion.get(i+1).split("_");
				nextTime = next_arr[4];
			}else {
				nextTime = df.format(new Date());
			}
			//匹配时间
			if(df.parse(createTime).getTime() <= df.parse(time).getTime()) {
				finalTime = time;
			}else if(df.parse(createTime).getTime() > df.parse(time).getTime() 
					&& df.parse(createTime).getTime()<df.parse(nextTime).getTime()) {
				finalTime = time;
			}
			if(finalTime != null) {
				break;
			}
		}
		if(finalTime != null) {
			name = version+"_"+depart+"_"+fzfl+"_"+finalTime;
		}
		if(null == name) {
			throw new Exception("no name");
		}
		/** 
		 * 1.先保存节点
		 * 2.再保存关系
		 * 3.节点添加关系
		 */
		Integer odid = mes.getOdid(syscode, cate);
		Integer scddhxppjgid = bl.getScddhxppjgid(syscode, cate);
		List<Map<String, Object>> stepList = bl.getStepList(scddhxppjgid);
		//查询节点
		List<Step> steps = createOrderStep(STEP_NAME+name,odid,stepList);
		// 组建DgraphSteps
		DgraphSteps dgraphStepOrder = new DgraphSteps();
		dgraphStepOrder.setD_steps_name(ORDER_STEP_NAME+version+"_"+syscode+"_"+odid);
		dgraphStepOrder.setSteps(steps);
		dgraphStepOrder.setParentStep(name);
		String json = gson.toJson(dgraphStepOrder);
		//保存节点
		ByteString muValue = ByteString.copyFromUtf8(json.toString());
    	Mutation mu = Mutation.newBuilder().setSetJson(muValue).build();
    	txn.mutate(mu);
    	//查询关系
		List<Relation> relations = createRelations(RELATION_NAME+name,steps);
		//组件DgraphRelations
		DgraphRelations dgraphRelationsOrder = new DgraphRelations();
		dgraphRelationsOrder.setD_relations_name(ORDER_RELATION_NAME+version+"_"+syscode+"_"+odid);
		dgraphRelationsOrder.setRelations(relations);
		dgraphRelationsOrder.setParentRelation(name);
		String json_rel = gson.toJson(dgraphRelationsOrder);
		//数据保存
		ByteString muValue_rel = ByteString.copyFromUtf8(json_rel.toString());
    	Mutation mu_rel = Mutation.newBuilder().setSetJson(muValue_rel).build();
    	txn.mutate(mu_rel);
    	//提交
    	txn.commit();
	}
	
	
	/**
	 * 
	 * <p>Title: createOrderStep</p>  
	 * <p>Description: </p>  
	 * @param syscode
	 * @param cj
	 * @param fzfl
	 */
	private List<Step> createOrderStep(String version,Integer odid,List<Map<String, Object>> stepList) {
		/**
		 * 1、拿着订单号，品类和车间匹配工序流图
		 * 2、拿着订单号和品类到MES数据库找odid
		 * 3、拿着订单号到BL数据库找工序列表
		 * 4、找到经过的节点和不经过的节点
		 * 5.经过的节点添加odid 和visible属性
		 * 6.不经过的节点不处理
		 */
		Iterator<Map<String, Object>> it = stepList.iterator();
		List<String> stepcodes = new ArrayList<String>();
		if (!it.hasNext()) {
			logger.info(odid + ":no step");
		}
		while (it.hasNext()) {
			Map<String, Object> row = it.next();
			stepcodes.add(row.get("ECODE").toString());
		}
		stepcodes.add("start");
		stepcodes.add("end");
		//获取所有的节点
		DgraphSteps dgraphSteps = stepService.getDgraphSteps(version);
		List<Step> steps = dgraphSteps.getSteps();
		//获取两个list相同的元素，以及不同的元素
		List<Step> needStep = new ArrayList<>();
		List<Step> notNeedStep = new ArrayList<>();
		for(Step st:steps) {
			if(stepcodes.contains(st.getKey())) {
				needStep.add(st);
			}else {
				notNeedStep.add(st);
			}
		}
		//处理包含的元素
		List<Step> newNeedSteps = new ArrayList<>();
		for(Step st:needStep) {
			st.setUid(null);
			st.setOdid(String.valueOf(odid));
    		st.setVisible(String.valueOf(odid));
    		newNeedSteps.add(st);
		}
		for(Step st:notNeedStep) {
			st.setUid(null);
			newNeedSteps.add(st);
		}
		//newNeedSteps.addAll(notNeedStep);
    	return newNeedSteps;
	}
	
	
	/**
	 * 
	 * <p>Title: createRelations</p>  
	 * <p>Description: </p>  
	 * @param name
	 * @return
	 */
	private List<Relation> createRelations(String version,List<Step> steps) {
		/**
		 * 1.循环不经过的节点
		 * 2.删除不经过节点的from 和 to 关系
		 * 3.创建新的from 和 to 的关系
		 * 4.保存关系
		 */
		DgraphRelations dgraphRelations = stepService.getDgraphRelation(version);
		List<Relation> relations = dgraphRelations.getRelations();
		for(Step st:steps) {
			if(StringUtils.isEmpty(st.getOdid())) {
				deleteRel(relations,st);
			}
		}
		for(Relation rel:relations) {
			rel.setUid(null);
		}
		return relations;
	}

	/**
	 * 
	 * <p>Title: deleteRel</p>  
	 * <p>Description: </p>  
	 * @param relations
	 * @param st
	 */
	private void deleteRel(List<Relation> relations, Step st) {
		List<Relation> formL = new ArrayList<Relation>();
		List<Relation> toL = new ArrayList<Relation>();
		String pre_step = null;
		String next_step = null;
		for(Relation rel:relations) {
			if(rel.getFrom().equals(st.getKey())) {
				formL.add(rel);
			}
			if(rel.getTo().equals(st.getKey())) {
				toL.add(rel);
			}
		}
		//
		if(formL != null && formL.size() == 1) {
			next_step = formL.get(0).getTo();
			relations.remove(formL.get(0));
		}
		if(toL != null && toL.size() == 1) {
			pre_step = toL.get(0).getFrom();
			relations.remove(toL.get(0));
		}
		if(null != pre_step && null != next_step) {
			//创建新关系
    		Relation relation = new Relation();
    		relation.setFrom(pre_step);
    		relation.setTo(next_step);
    		relations.add(relation);
		}
	}

}
